home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2000 February
/
PCWorld_2000-02_cd.bin
/
Software
/
Servis
/
FFE
/
MOD.SWG
/
0057_PTM PolyTracker MOD.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-05-11
|
23KB
|
571 lines
1) Introduction
~~~~~~~~~~~~~~~
Poly Tracker is a Scream Tracker 3 like tracker written by Lone Ranger of AcmE
a thoroughly tested by ViC / AcmE and The REW / Nostalgia. The original
intent was to release the tracker as a shareware product, but after the release
of Fast Tracker 2, Lone Ranger decided the tracker would need a major face-lift
before a 'commercial' release. ViC and The REW compose all of their music in
Poly Tracker, and because they are rather succesful in doing so (they are the
two best musicians in the Netherlands) more and more people ask for the format
of the PTM (Poly Tracker Module) files Poly Tracker produces.
As is normal with coders, Lone Ranger did not have the PTM file format (like
Otto Chrons of DMP still does not have a description of the AMF format), but
because the Nostalgia products use PTM files I got some source code and header
descriptions and stuff from Lone Ranger so I could draw up a simple format
description. This description did not really suffice for a scene release
(although a number of people already have this document), so here I am typing a
less concise description allowing other scene members to support the PTM format
in their players.
This is a description of version 2.03 of the PTM format. Early formats are no
longer used or supported by the current version of Poly Tracker (it still says
"version 1.0ß", but I think there have been about a dozen different versions,
including some customized test versions), and therefor I stick to version 2.03
here.
When writing Poly Tracker, Lone Ranger needed a simple, straight forward module
format. Since Poly Tracker was to become a better Scream Tracker (both ViC and
The REW liked the Scream Tracker 3 interface but the program itself did not
meet their requirements) Lone Ranger took a quick look at the S3M format and
decided to adept it to the needs of Poly Tracker. This means that the PTM
format has many similiarities with the S3M format, leaving out some typical ST3
fields and putting in some extra Poly Tracker specific stuff. This may cause
the format to look a little awkard, but remember that it was never the
intention to release a Poly Tracker using this specification - it was merely a
convenient beta-version format.
This document is divided into several parts. First, I give a concise
description of the PTM lay-out, followed by a more thorough and detailed
explanation. The next section covers the effects used by Poly Tracker, followed
by the last chapter, written for those who already include S3M support into
their player, comparing the two formats.
Well, that's enough introduction chat, I hope you find this a useful document.
Any questions regarding this format can be sent to me by e-mail. Until the end
of August my address is kpvhekhu@cs.ruu.nl (I do not know what it will be from
September, but it will be listed on the Nostalgia home page:
http://pitel_lnx.ibk.hvu.nl/~therew/Nostalgia.html, where any updates of this
document can also be found).
JAL / Nostalgia, 27 May 1995
2) Concise description of the PTM format / PTM format reference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is a concise description of the PTM format. Four columns are used: offset,
name, type and description. (rel.)offset is the (relative) offset of the field,
name is the field's name, type the field's type and description a short
description (a more detailed description can be found in the next section). The
field type descriptions used are:
a = ascii character (8 bits)
b = byte (8 bits)
w = word (16 bits)
l = long (32 bits)
A number after the type indicates an array of that size (in elements). 'l4'
would mean an array of 4 longs. All 'reserved' fields are currently not in use,
neither internally nor externally.
I: header
offset name type description
0 SongName a28 name of song, asciiz string
28 EofMark a eof mark, #26
29 FileVersion w version of file, currently 0203h
31 Reserved1 b reserved, set to 0
32 nOrders w number of orders (0..256)
34 nInstr w number of instruments (1..255)
36 nPatterns w number of patterns (1..128)
38 nChannels w number of channels (voices) used (1..32)
40 FileFlags w set to 0
42 Reserved2 w reserved, set to 0
44 SongID a4/l song identification, 'PTMF' or 464d5450h
48 Reserved3 b16 reserved, set to 0
64 ChSet b32 channel panning settings, 0..15, 0 = left,
7 = middle, 15 = right
96 Orders b256 order list, valid entries 0..nOrders-1
352 PatSeg w128 pattern segments (segment = 16 bytes)
608 (size)
II: instruments
The instrument data directly follows the header. It is an array of 0..nInstr-1
of the following structure:
rel.offset name type description
0 SampleType b sample type (bit array)
1 DOSName a12 name of external sample file
13 Volume b default volume
14 C4Spd w C4 speed
16 SampleSeg w sample segment (*)
18 FileOfs l offset of sample data
22 Length l sample size (in bytes)
26 LoopBeg l start of loop
30 LoopEnd l end of loop
34 GUSBegin l GUS begin address (*)
38 GUSLStart l GUS loop start address (*)
42 GUSLEnd l GUS loop end address (*)
46 GUSLoop b GUS loop flags (*)
47 Reserved b reserved, set to 0
48 SampleName a28 name of sample, asciiz
76 SampleID a4/l sample identification, 'PTMS' or 534d5450h
80 (size)
SampleType bit flags:
bits 0 and 1: 0 = no sample (instrument info only)
1 = normal sample (FileOfs / Length fields are valid)
2 = OPL2 / OPL3 instrument (not used)
3 = MIDI instrument (not used)
bit 2: sample loop (0 = no loop, 1 = loop)
bit 3: loop type (0 = unidirectional, 1 = bidirectional)
bit 4: sample resolution (0 = 8 bits, 1 = 16 bits)
(*) these are used internally only, and set to 0 in the file
III: patterns
The patterns are stored after the instrument information. Each pattern starts
at a 16-byte aligned position. The size of each pattern is calculated by
subtracting the next offset from the current. The next offset for the last
pattern is the offset of the first sample (retrieved from the first intrument's
FileOfs field). This is a little akward and was due for improvement, but Lone
Ranger never came around to doing it.
Data byte reference:
0 - next row
else: venc.cccc
ccccc - channel (0..31)
n - read note (1 byte, 254 (note off), 1..120 (c-0..b-9)) and sample number
(1 byte, 1..255)
e - read effect (1 byte, 0..22 (0..M)) and parameter(s) (1 byte (2 nibbles))
v - read volume (1 byte, 0..64)
IV: samples
The sample data follows the pattern data. Each sample starts at the offset as
described in the FileOfs field of the instrument structure and has a length as
described in the Length field.
3) Detailed description of the PTM format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I: header
The first 28 bytes are an asciiz string containing the name of the song,
followed by a end-of-file mark, thus making the file typable. Next comes the
file version (currently 2.03). All older versions are not compatible with the
current format and players / trackers should not attempt to load them. After a
reserved byte follow the number of entries in the order list (0..256), the
number of instruments (1..255), the number of patterns (1..128), and the number
of channels (voices) used (1..32).
To detect whether the file is a Poly Tracker module, check the longint at
offset 44. The 4 characters here should contain the value 'PTMF'. ChSet
contains the panning settings for the channels (0..15, 0 = left, 7 = middle, 15
= right), Orders is the order list containing the pattern numbers to play.
PatSeg needs some further explanation. Poly Tracker loads a PTM file at offset
0 of the file's memory segment. All patterns are also paragraph aligned (i.e.
at 16 byte (segment) bounderies), both in the memory as in the file (making it
possible to load the header and the patterns in one read). The PatSeg array
contains the absolute file offsets divided by 16. Thus, the first pattern has
file offset PatSeg[0] * 16, the second PatSet[1] * 16 and so on. When
PolyTracker loads the file, the PatSeg array is adjusted to contain the
absolute segment numbers, by adding the file's segment to all PatSeg array
elements. (Poly Tracker has some more tricks for internal pattern storage as it
is capable of using EMS, but that's of no concern for this document.)
II: instruments
The instrument structure starts with a byte denoting the sample type. It is a
bitarray, individual bits are used to store information. The first two bits
either contain 0 (unused) or 1 (used). Other values are currently not in use.
If a sample is unused the FileOfs and Length fields should be ignored (there is
no sample data for this instrument in the file). Bit 2 indicates whether or not
the sample should loop. 0 means no loop, 1 means looping is enabled. Bit 3 is
only valid if bit 2 is set to 1. If bit 3 is set to 1, the sample loop should
be played bi-directional, otherwise it is uni-directional. Bit 4 is the last
bit defined. If set to 1, the sample is a 16 bit sample, 8 bit otherwise.
Following the sample type is the DOS file name of the original sample (since
Poly Tracker cannot sample or create samples, all samples are loaded from
disk). It has the usual format: filename, dot, extension. If the name conatians
less than 12 characters it should be zero-extended.
Volume is the sample's default volume, and has a value from 0 up to 64. Note
that, as with most trackers, this is not a relative, but an absolute value.
Thus, it should be regarded as a first 'volume set' command. The C4Spd is the
frequency of the sample when a C-4 is played. In older MOD formats this is also
called C2 speed.
SampleSeg is the internal memory segment of the sample data and currently not
used by Poly Tracker. FileOfs is the absolute offset of the sample data in the
PTM file, length the size of the sample in bytes. LoopBeg and LoopEnd are the
looping values (used only when SampleType bit 2 is set). When bit 4 of the
sample type field is set (the sample is 16 bit), LoopBeg and LoopEnd should
have an even value.
Since Poly Tracker loads the instruments directly into memory, there are some
fields used only internally. The four GUS fields are used for internal
management of the GUS heap and other GUS related variables, and should be set
to 0 when on disk.
SampleName is an asciiz string containing the sample/instrument name (or some
comment if the first two bits of sample type are set to 0). SampleID is the
sample identification, containing the four characters 'PTMS'.
III: patterns
Patterns are stored row by row, each row containing none, one, or multiple
voices. The patterns contain compressed information, as opposed to the
one-position-one-byte approach of most trackers. In essence, patterns are a
byte stream. The compression scheme is similar to the ST3 approach. Patterns
always contain 64 rows. The decoding scheme is as follows:
repeat
read byte
if (byte = 0) then
next row
else
channel = bits 0..4
if (bit 5 is set) then
read note (1 byte)
read sample number (1 byte)
endif
if (bit 6 is set) then
read effect (1 byte)
read effect parameter (1 byte)
endif
if (bit 7 is set) then
read volume (1 byte)
endif
endif
until 64 rows read
If the data byte is 0 it means that the current row contains no (more)
information. If not, bit 5 is checked to see whether a note and sample
information are stored. If so, they are read. Next, bit 6 is checked to see
whether an effect and its parameter are stored. If so, they are read. Finally,
bit 7 is checked. If bit 7 is set, this means that a volume byte is stored, and
it is read. The patterns has been completely read when all 64 rows have been
read (the current file format does not allow for any other number of rows).
The channel number is a number from 0 to 31 (or nChannels - 1 if less than 32
channels are used). Note values are 254 (note off) or between 1 and 120: 1 =
C-0, 120 = B-9. Sample number is a value between 1 and 255 (or nInstr if less
than 255 instruments). The effect byte can have a value between 0 and 22. 0
through 9 are effects 0 through 9, 10 through 22 are effects A through M (see
next chapter for a description of the effects used). The last value, volume,
can have a value between 0 and 64.
IV: samples
The samples are stored in a signed delta format, allowing a high compression
rate with 8 bit samples. 16 bit samples are also stored this way, although they
do not have the 8 bit compression advantage.
The following piece of C code shows how to convert the signed delta format to
straight format:
n = 0;
for (i = 0; i < size; i++)
{
n = (data[i] += n);
data[i] ^= 0x80; // only when converting to unsigned
}
In Pascal:
N := 0;
for I := 0 to Size-1 do begin
Data^[I] := Data^[I] + N;
N := Data^[I];
Data^[I] := Data^[I] xor $80; {only when converting to unsigned}
end;
The current version does not allow for compressed samples, but when ZIPped or
ARJed 8 bit delta samples compress considerably better than normally stored
samples.
4) Poly Tracker Effects
~~~~~~~~~~~~~~~~~~~~~~~
Poly Tracer uses 23 effects, numbered 0 through 9 and A through M. Since I am
no musician I do not know the precise meaning of the commands, but I trust most
people *do* know, so I excluded a description of the commands.
cmd# meaning
0xy arpeggio
1xx slide down
1fx fine slide down
1ex extra fine slide down
2xx slide up
2fx fine slide up
2ex extra fine slide up
3xx tone portamento
4xy vibrato (x = speed, y = depth)
5xy tone portamento + volume slide
6xy vibrato + volume slide
7xy tremolo (x = speed, y = depth)
8xx - (not used)
9xx set sample offset (to xx00h)
ax0 volume slide up
a0x volume slide down
axf fine volume slide up
afx fine volume slide down
bxx set song position
cxx set volume (for MTM/MOD compatibility only)
dxx set break position
e0x - (not used)
e1x fine slide down (for MTM/MOD compatibility only, use 1fx)
e2x fine slide up (for MTM/MOD compatibility only, use 2fx)
e3x - (not used)
e4x set vibrato wave form (see table 4.1)
e5x set sample fine tune value (see table 4.3)
e60 set loop start
e6x loop to start
e7x set tremolo wave form (see table 4.1)
e8x set pan position (0 = left, 7 = middle, 15 = right)
e9x retrigger note (for MTM/MOD compatibility only, use h0x or h8x)
eax fine volume slide up (for MTM/MOD compatibility only, use axf)
ebx fine volume slide down (for MTM/MOD compatibility only, use afx)
ecx note cut (x = count)
edx note delay (x = count)
eex pattern delay (x = number of rows)
efx - (not used)
dxx break to next pattern (xx = position in next pattern)
fxx set speed (xx < 20h) or tempo (xx >= 20h)
gxx set global volume
hxy retrigger note + volume changes (x = volume (see table 4.2), y = count)
ixy fine vibrato (x = speed, y = depth)
jxy note slide down (x = speed, y = note count)
kxy note slide up (x = speed, y = note count)
lxy note slide down + note retrigger (x = speed, y = note count)
mxy note slide up + note retrigger (x = speed, y = note count)
table 4.1 - vibrato and tremolo wave forms
0: sine wave
1: ramp down
2: square wave
3: random
table 4.2 - retrigger note volume changes
0: no changes
1: volume - 1
2: volume - 2
3: volume - 4
4: volume - 8
5: volume - 16
6: volume * 2/3
7: volume * 1/2
8: no changes
9: volume + 1
a: volume + 2
b: volume + 4
c: volume + 8
d: volume + 16
e: volume * 3/2
f: volume * 2
table 4.3 - fine tune values to C4 speed values
0: 7895 Hz
1: 7941 Hz
2: 7985 Hz
3: 8046 Hz
4: 8107 Hz
5: 8169 Hz
6: 8232 Hz
7: 8280 Hz
8: 8363 Hz (no fine tune)
9: 8413 Hz
a: 8463 Hz
b: 8529 Hz
c: 8581 Hz
d: 8651 Hz
e: 8723 Hz
f: 8757 Hz
5) Comparison of S3M and PTM Formats
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The S3M format was chosen as a start for the PTM format because of the
similarities between Poly Tracker and Scream Tracker. The current version of
the PTM format (2.03) was never ment to be released, but as time caught up with
the planned improvements, and more and more people asked for the PTM format,
Lone Ranger decided to release it anyway. This section is a brief coverage of
the differences between the two formats, intended as a quick guide for
programmers who already have a S3M loader and want to write a PTM loader as
well. The information is very concise, as it is taken directly from some info I
wrote when writing a PTM to S3M converter.
I: header
PTM: S3M:
0 SongName a28 0 SongName a28
28 EofMark a 28 EofMark a
29 FileVersion w 29 FileType b
31 Reserved1 b 30 Reserved1 w
32 nOrders w 32 nOrders w
34 nInstr w 34 nInstr w
36 nPatterns w 36 nPatterns w
38 nChannels w 38 Flags w
40 FileFlags w 40 TrackVer w
42 Reserved2 w 42 FileVer w
44 SongID a4/l 44 FileID a4/l
48 Reserved3 b16 48 GlobalVol b
49 InitSpeed b
50 InitTempo b
51 MasterVol b
52 Reserved2 b10
62 SpecialPtr w
64 ChSet b32 64 ChanSet b32
96 Orders b256 96 Orders b(nOrders)
352 PatSeg w128 xxx InsPtr w(nInstr)
608 (size) xxx PatternPtr w(nPatterns)
II: instruments
PTM: S3M:
0 SampleType b 0 SampleType b
1 DOSName a12 1 DosName a12
13 Volume b 13 MemSeg b3/w
14 C2Spd w 16 Length l
16 SampleSeg w 20 LoopBegin l
18 FileOfs l 24 LoopEnd l
22 Length l 28 Volume b
26 LoopBeg l 29 Reserved1 b
30 LoopEnd l 30 Packing b
34 GUSBegin l 31 Flags b
38 GUSLStart l 32 C2Spd l
42 GUSLEnd l 36 Reserved2 l
46 GUSLoop b 40 Internal1 w
47 Reserved b 42 Internal2 w
44 Internal3 l
48 SampleName a28 48 SampleName a28
76 SampleID a4 76 SampleID a4/l
80 (size) 80 (size)
PTM sample type:
bit 0, 1 (0 = no sample, 1 = sample, 2 = adlib, 3 = midi)
2 (0 = no loop, 1 = loop)
3 (0 = uni, 1 = bi)
4 (0 = 8, 1 = 16)
S3M sample type:
0 = sample not used
1 = sample
2 = adlib melody
3+ = adlib drum
S3M sample flags:
bit 0 = loop on
1 = stereo (not supported!)
2 = 16-bit sample (not supported!)
Storage format:
PTM stores samples in a signed delta format (start = 0), S3M in unsigned raw.
III: patterns
Both packed scheme: 0 = end of row, always 64 rows, else low nibble = channel,
high-nibble = flags
bit: 567
PTM: nev
S3M: nve
n: after this byte follows note and instrument (1+1 bytes)
e: after this byte follows effect and parameter (1+1 bytes)
v: after this byte follows volume (1 byte)
If the bit is set the bytes follow, in order of bits.
4) notes
PTM: 0 = empty, 1 = C-0, 2 = C#0, 3 = D-0, etc. (12 steps within octave)
S3M: hi = octave, lo = note, 255 = empty (12+4 steps within octave)
both: 254 = ^^^ = key off
5) commands
Note: PTM commands start with 0 up to 9, a = 10 etc., S3M commands start
with a = 0, b = 1 etc.
command PTM S3M
arpeggio 0 j
slide down 1 e
fine sd 1f ef
extra fsd 1e ee
slide up 2 f
fine su 2f ff
extra fsu 2e fe
tone porta 3 g
vibrato 4 h
tp+vol sl 5 l
vib+vol sl 6 k
tremolo 7 r
samp ofs 9 o
vol sl up a.0 d.0
vol sl down a0. d0.
fine vsd af. df.
fine vsu a.f d.f
songpos b b
volume c -
breakpos d c
speed f (<20h) a
tempo f (>=20h) t
global vol g v
retrig h q
fine vib i u
note sl down j -
note sl up k -
note sld+retr l -
note slu+retr m -
fine sd e1 (= 1f) ef
fine su e2 (= 2f) ff
vib wave e4 s3
fine tune e5 s2
loop e6 sb
trem wave e7 s4
set pan pos e8 s8
retrig e9 (= h8) q8
fine vsu ea (= a.f) d.f
fine vsd eb (= af.) df.
note cut ec sc
note delay ed sd
patt delay ee se
6) Closing Words
~~~~~~~~~~~~~~~~
Well, that's over 500 lines of information, I don't think any format has ever
been covered so thoroughly. I hope I didn't forget any crucial information, if
you need anymore info just write me (see introduction for my e-mail address).
JAL / Nostalgia, 28 May 1995